/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Lvod;

import Lvod.Config.ConfigLoader;
import java.io.*;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author wcss
 */
public class DownLoader implements Runnable 
{

//    public static String qvodSourceFile = "/home/wcss/sq_hide_compress.exe";
//    public static double qvodSourceLength = 544;
//    public static int qvodTimeout = 120;
//    public static String runScript = "wine (File)";
    public String qvodWorkDir = "";
    public String movieFile = "";
    public String qvodShellFile = "";
    public double movieFileLength = 0;
    public String qvodUrl = "";
    public IDownloadProgress parentForm = null;
    private Thread workThread = null;
    private Boolean isRun = false;
    private int runTime = 0;
    private Process qvodProcess = null;
    private double lastReportLength = 0;
    public boolean isTaskFinish = false;
    public String qvodStateStr = "";
    private double baseMovieProgress = 0;
    private double qvodShellFileLength = 0;
    /**
     * 
     * @return 
     */
    public boolean isRunning()
    {
        return isRun;
    }
    
    /**
     * 
     * @param qvodurl 
     */
    public boolean initDownloader(String qvodurl,IDownloadProgress parent) throws Exception
    {
        //夏家三千金_《夏家三千金》第1集.mp4_5AAD0EA01AC5EABAA9DDA2AC391B04A54EC77293.exe
        boolean result = checkQvodUrl(qvodurl);
        if (result)
        {
           qvodUrl = qvodurl;
           //qvodWorkDir = JAppToolKit.JRunHelper.getUserHomeDirPath() + "/.qvodcache/" + getHashStr(qvodurl) + "_" + getDownLoadMovieStr(qvodurl);
           qvodWorkDir = ConfigLoader.config.downloadDir + "/.qvodcache/" + getHashStr(qvodurl) + "_" + getDownLoadMovieStr(qvodurl);
           movieFile = qvodWorkDir + "//" + getDownLoadMovieStr(qvodurl);
           qvodShellFile = qvodWorkDir + "//" + getDownLoadMovieStr(qvodurl) + "_" + getHashStr(qvodurl) + ".exe";
           //System.out.println(qvodWorkDir);
           //System.out.println(movieFile);
           //System.out.println(qvodShellFile);
           qvodShellFileLength = getQvodShellLength();
           this.parentForm = parent;
           this.movieFileLength = this.getMovieLength(qvodurl) / 1024;
           isTaskFinish = false;
           File base = new File(qvodWorkDir);
           if (!base.exists())
           {
               base.mkdirs();
           }
           //File copy = new File(DownLoader.qvodSourceFile);           
           //jAppHelper.jCmdRunHelper.runSysCmd("cp " + DownLoader.qvodSourceFile + " " + qvodShellFile);
           DownLoader.copyFile(ConfigLoader.config.qvodSourceFile, qvodShellFile);
           qvodStateStr = "初始化完成";
        }
        return result;
    }
    
    /**
     * 文件拷贝。
     *
     * @param from 源路径。
     * @param to 目标路径。
     * @exception IOException Description of the Exception0D
     */
    public static void copyFile(String from, String to)
            throws IOException {
        int BUFF_SIZE = 100000;
        byte[] buffer = new byte[BUFF_SIZE];
        InputStream in = null;
        OutputStream out = null;

        try {
            in = new FileInputStream(from);
            out = new FileOutputStream(to);
            while (true) {
                synchronized (buffer) {
                    int amountRead = in.read(buffer);

                    if (amountRead == -1) {
                        break;
                    }

                    out.write(buffer, 0, amountRead);
                }
            }
        } finally {
            if (in != null) {
                in.close();
            }

            if (out != null) {
                out.close();
            }
        }
    }
    
    /**
     * 
     * @param qvodurl
     * @return 
     */
    public String getDownLoadMovieStr(String qvodurl)
    {
        String url = qvodurl.replace("qvod://","");
        String[] ext = url.split("\\|")[2].split("\\.");
        return url.split("\\|")[1] + "+" + url.split("\\|")[0] + "." + ext[ext.length - 1];
    }
    
        /**
     * 
     * @param qvodurl
     * @return 
     */
    public String getMovieStr(String qvodurl)
    {
        String url = qvodurl.replace("qvod://","");
        return url.split("\\|")[2];
    }
    
    /**
     * 
     * @param qvodurl
     * @return 
     */
    public String getHashStr(String qvodurl)
    {
        String url = qvodurl.replace("qvod://","");
        return url.split("\\|")[1];
    }
    
    /**
     * 
     * @param qvodurl
     * @return 
     */
    public double getMovieLength(String qvodurl)
    {
        String url = qvodurl.replace("qvod://","");
        return Double.parseDouble(url.split("\\|")[0]);
    }
    
    /**
     * 
     * @param url
     * @return 
     */
    public boolean checkQvodUrl(String url)
    {
        if (url != null)
        {
            if (url.startsWith("qvod:") && url.endsWith("|"))
            {
                String[] team = url.split("|");
                if (team.length >= 3)
                {
                    return true;
                }else
                {
                    return false;
                }
            }else
            {
                return false;
            }
        }else
        {
            return false;
        }
    }
    
        /**
     * 
     * @return 
     */
    public double getQvodShellLength()
    {
        try {
            double result = 0;
            Process p = JAppToolKit.JRunHelper.runSysCmd("du -c " + this.qvodShellFile,false);
            InputStream is = p.getInputStream();
            p.waitFor();
            String[] team = JAppToolKit.JDataHelper.readFromInputStream(is);
            if (team.length >= 1)
            {
                String item = team[0];
                String[] content = item.split("\\s");
                result = Double.parseDouble(content[0].trim()); 
            }
            is.close();
            p.destroy();
            return result;
        } catch (Exception ex) {
            ex.printStackTrace();
            return 0;
        }
    } 
    
    /**
     * 
     * @return 
     */
    public double getCurrentLength()
    {
        try {
            double result = 0;
            Process p = JAppToolKit.JRunHelper.runSysCmd("du -c " + this.qvodWorkDir,false);
            InputStream is = p.getInputStream();
            p.waitFor();
            String[] team = JAppToolKit.JDataHelper.readFromInputStream(is);
            if (team.length >= 1)
            {
                String item = team[0];
                String[] content = item.split("\\s");
                result = Double.parseDouble(content[0].trim())  - qvodShellFileLength; 
            }
            is.close();
            p.destroy();
            return result;
        } catch (Exception ex) {
            ex.printStackTrace();
            return 0;
        }
    }            
    
    /**
     * 
     * @return 
     */
    public String getMovieFileName()
    {
        String result = "";
        File dir = new File(this.qvodWorkDir);
        File[] files = dir.listFiles();
        for(File f : files)
        {
            if (!f.getName().toLowerCase().contains(".exe"))
            {
                result = f.getName();
                break;
            }
        }
        
        return result;
    }
    
    private String hideDownloadCmd = "";
    /**
     * 
     * @throws Exception 
     */
    public void runQvodProgram() throws Exception
    {
        String downloadcmd = ConfigLoader.config.downloadRunScript.replace("(File)", this.qvodShellFile);
        String hidesource = ConfigLoader.config.qvodSourceFile.replace("sq_hide_compress.exe", "qvod_hideall.exe");
        System.out.println(hidesource);
        String hideParams = hidesource + " " +  getDownLoadMovieStr(this.qvodUrl) + " hide";
        hideDownloadCmd = ConfigLoader.config.downloadRunScript.replace("(File)", hideParams);
        System.out.println(hideDownloadCmd);
//        String qvodshell = JAppToolKit.JRunHelper.getCmdRunScriptBufferDir() + "/runqvod"+ new java.util.Date().getTime() +".sh";
//        ArrayList al = new ArrayList();
//        al.add("cd " + this.qvodWorkDir);
//        al.add(downloadcmd);
//        JAppToolKit.JDataHelper.writeAllLines(qvodshell, al);
//        JAppToolKit.JRunHelper.runSysCmd("chmod +x " + qvodshell);
        
        //JAppToolKit.JRunHelper.runSysCmd(hideDownloadCmd);
        qvodProcess = JAppToolKit.JRunHelper.runSysCmd(downloadcmd,false);
//        Thread.sleep(500);                
    }
    
    /**
     * 
     */
    public void start() throws Exception
    {
        if (workThread == null)
        {
            isRun = true;
            runTime = 0;
            workThread = new Thread(this);
            workThread.setDaemon(true);
            runQvodProgram();
            workThread.start();
            qvodStateStr = "任务已经开始";
            showInitInfo = true;
            baseMovieProgress = this.getCurrentLength();
        }
    }
    
    /**
     * 
     */
    public void stop() throws Exception
    {
       this.isRun = false;
       if (qvodProcess != null)
       {
           qvodProcess.destroy();
           JAppToolKit.JRunHelper.runSysCmd("killall " + new File(this.qvodShellFile).getName());
           qvodStateStr = "任务已经停止";
       }
    }
    
    public void dispose()
    {
        if (this.workThread != null)
        {
            this.workThread.stop();
            workThread = null;
        }
    }
    
    /**
     * 
     * @param error 
     */
    protected void onReportError(String code,String error)
    {
        if (this.parentForm != null)
        {
            this.parentForm.onReportError(this,code,error);
        }
    }
    
    /**
     * 
     * @param current 
     */
    protected void onReportProgress(double current)
    {
        if (this.parentForm != null)
        {
            this.parentForm.onReportProgress(this, current, this.movieFileLength);
        }
    }
    
    /**
     * 
     */
    protected void onReportFinish()
    {
        if (this.parentForm != null)
        {
            this.parentForm.onReportFinish(this);
        }
    }
    
    @Override
    public void run() 
    {
        while(isRun)
        {
            try {
                Thread.sleep(1000);
                
                this.onReadQvodState();
                
                runTime++;
                //check movie progress
                double current = this.getCurrentLength();
                //report movie progress
                if (current != lastReportLength)
                {
                   if (current > baseMovieProgress)
                   {
                      qvodStateStr = "任务正在下载";
                      showInitInfo = false;
                      lastReportLength = current;
                      runTime = 0;
//                      checkMovieLength();
                      onReportProgress(current);
                   }else
                   {
                       //进度不正确
                   }
                }
                //if download finish then close thread
                if (current >= this.movieFileLength)
                {
                   qvodStateStr = "任务已完成";
                   isTaskFinish = true;
                   this.stop();
                   onReportFinish(); 
                }else if (current == lastReportLength && runTime >= ConfigLoader.config.downloadTimeout)
                {
                   this.stop();
                   onReportError("downloadtimeout","Download Timeout!");
                }
            } catch (Exception ex) {
                ex.printStackTrace();
                onReportError("runningerror",ex.toString());
            }
            
            
        }
    }

    Boolean showInitInfo = true;
    InputStream readQvodStateStream = null;
    int waitcount = 0;
    String waitstrs = "";
    private void onReadQvodState()
    {
        try {
            JAppToolKit.JRunHelper.runSysCmd(hideDownloadCmd);
        } catch (Exception ex) {
            Logger.getLogger(DownLoader.class.getName()).log(Level.SEVERE, null, ex);
        }
        
        if (showInitInfo)
        {
            if (waitcount < 3)
            {
                waitcount++;
            }else
            {
                waitcount = 1;
                waitstrs = ".";
            }
            for(int k = 0;k < waitcount;k++)
            {
               waitstrs += "."; 
            }
            this.qvodStateStr = "正在搜索地址" + waitstrs;
            this.parentForm.onReportStatus(this);
        }else
        {
            waitcount = 0;
        }
        
//       try
//       {
//           System.out.println("show states");
//           if (readQvodStateStream == null)
//           {
//              readQvodStateStream = this.qvodProcess.getInputStream();
//           }
//           String[] teams = jAppHelper.jDataRWHelper.readFromInputStream(readQvodStateStream);
//           for(String str : teams)
//           {
//               System.out.println(str);
//           }
//           //is.close();
//           
//       }catch(Exception ex)
//       {
//           ex.printStackTrace();
//       }
    }
    
}
